package com.cloudxingkong.dianyinke.Student.Class;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
 * Created by ningfei on 2016/4/5.
 */
public class ImageLoaderFromPZ {
    private static final String TAG = "ImageLoader";
    private static final int MAX_CAPACITY = 10;// 一级缓存的最大空间
    private static final long DELAY_BEFORE_PURGE = 100* 1000;// 定时清理缓存

    // 0.75是加载因子为经验值，true则表示按照最近访问量的高低排序，false则表示按照插入顺序排序
    private HashMap<String, Bitmap> mFirstLevelCache = new LinkedHashMap<String, Bitmap>(
            MAX_CAPACITY / 2, 0.75f, true) {
        private static final long serialVersionUID = 1L;

        protected boolean removeEldestEntry(Entry<String, Bitmap> eldest) {
            if (size() > MAX_CAPACITY) {// 当超过一级缓存阈值的时候，将老的值从一级缓存搬到二级缓存
                mSecondLevelCache.put(eldest.getKey(),
                        new SoftReference<Bitmap>(eldest.getValue()));
                return true;
            }
            return false;
        };
    };
    // 二级缓存，采用的是软应用，只有在内存吃紧的时候软应用才会被回收，有效的避免了oom
    private ConcurrentHashMap<String, SoftReference<Bitmap>> mSecondLevelCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(
            MAX_CAPACITY / 2);

    // 定时清理缓存
    private Runnable mClearCache = new Runnable() {
        @Override
        public void run() {
            clear();
        }
    };
    private Handler mPurgeHandler = new Handler();

    // 重置缓存清理的timer
    private void resetPurgeTimer() {
        mPurgeHandler.removeCallbacks(mClearCache);
        mPurgeHandler.postDelayed(mClearCache, DELAY_BEFORE_PURGE);
    }

    /**
     * 清理缓存
     */
    private void clear() {
        mFirstLevelCache.clear();
        mSecondLevelCache.clear();
    }

    /**
     * 返回缓存，如果没有则返回null
     *
     * @param url
     * @return
     */
    public Bitmap getBitmapFromCache(String url) {
        Bitmap bitmap = null;
        bitmap = getFromFirstLevelCache(url);// 从一级缓存中拿
        if (bitmap != null) {
            return bitmap;
        }
        bitmap = getFromSecondLevelCache(url);// 从二级缓存中拿
        return bitmap;
    }

    /**
     * 从二级缓存中拿
     *
     * @param url
     * @return
     */
    private Bitmap getFromSecondLevelCache(String url) {
        Bitmap bitmap = null;
        SoftReference<Bitmap> softReference = mSecondLevelCache.get(url);
        if (softReference != null) {
            bitmap = softReference.get();
            if (bitmap == null) {// 由于内存吃紧，软引用已经被gc回收了
                mSecondLevelCache.remove(url);
            }
        }
        return bitmap;
    }

    /**
     * 从一级缓存中拿
     *
     * @param url
     * @return
     */
    private Bitmap getFromFirstLevelCache(String url) {
        Bitmap bitmap = null;
        synchronized (mFirstLevelCache) {
            bitmap = mFirstLevelCache.get(url);
            if (bitmap != null) {// 将最近访问的元素放到链的头部，提高下一次访问该元素的检索速度（LRU算法）
                mFirstLevelCache.remove(url);
                mFirstLevelCache.put(url, bitmap);
            }
        }
        return bitmap;
    }



    /**
     * 加载图片，如果缓存中有就直接从缓存中拿，缓存中没有就从sd卡中取
     * @param url
     * @param
     * @param
     */
    public void loadImageFormSD(String url, List<View> views,List fileS) {
        resetPurgeTimer();
        for(int i=0;i<views.size();i++){
            ImageView img=(ImageView)views.get(i);
            Bitmap bit=getBitmapFromCache((String)fileS.get(i));
            if(bit!=null){
                img.setImageBitmap(bit);
            }
        }

    }

    /**
     * 放入缓存
     *
     * @param url
     * @param value
     */
    public void addImage2Cache(String url, Bitmap value) {
        if (value == null || url == null) {
            return;
        }
        synchronized (mFirstLevelCache) {
            mFirstLevelCache.put(url, value);
        }
    }

    class ImageLoadTask1 extends AsyncTask<Object, Void, Bitmap> {
        String url;
        List<View> views;
        List fileS;
        @Override
        protected Bitmap doInBackground(Object... params) {
            url = (String) params[0];
            views=(List<View>)params[1];
            fileS=(List)params[2];
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inSampleSize = 1;
            opt.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(url, opt);
            int bitmapSize = opt.outHeight * opt.outWidth * 4;
            opt.inSampleSize = bitmapSize / (1000 * 2000);
            opt.inJustDecodeBounds = false;
            Bitmap drawable = BitmapFactory.decodeFile(url, opt);
            drawable = ThumbnailUtils.extractThumbnail(drawable,
                    100,100,
                    ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
            return drawable;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (result == null) {
                return;
            }
            addImage2Cache(url, result);// 放入缓存
            //adapter.notifyDataSetChanged();// 触发getView方法执行，这个时候getView实际上会拿到刚刚缓存好的图片

        }
    }

}
